package com.comp437.uno.model;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;

import com.comp437.uno.view.playboard.PlayBoard;
import com.comp437.uno.view.playroom.PlayRoomView;
import com.comp437.uno.view.playroomlist.PlayRoomListView;

import message.message;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;

/**
 * Make sure to check the socket isConnected() before call other socket related
 * function
 * 
 * Here it is the service provided the connection service
 * 
 * !!!!!!!NOTICE!!!!!CAUTION!!!!! This class has MANY PROBLEMS .......
 * 
 */
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public class ClientService extends Service {

	Model model;
	static Thread temp;

	private Socket socket;
	private int serverport;
	private String server_ip;
	
	protected static Handler receiveServer = null;
	private SocketReader ReaderThread;
	private SocketWriter WriterThread;
	protected static boolean started=false;
	ObjectInputStream in = null;
	ObjectOutputStream out = null;
	// Binder given to clients
	private final IBinder mBinder = new LocalBinder();

	// Random number generator

	/**
	 * Class used for the client Binder. Because we know this service always
	 * runs in the same process as its clients, we don't need to deal with IPC.
	 */
	public class LocalBinder extends Binder {
		public ClientService getService() {
			// Return this instance of LocalService so clients can call public
			// methods
			return ClientService.this;
		}
	}

	@Override
	public IBinder onBind(Intent intent) {
		return mBinder;
	}

	@TargetApi(Build.VERSION_CODES.GINGERBREAD)
	@SuppressLint("NewApi")
	@Override
	public void onCreate() {

		Log.e("Chat", "start onStart~~~");
		// TODO Auto-generated method stub
		if (model == null)
			model = Model.getModel();

	}

	public void login(String username, String password, int flag) {
		if (WriterThread != null){
			WriterThread.setMessage(username, password, flag);
			
		}else
			Log.i("Cs", "Login");
		
	}
	
	public void signup(String username, String password, int flag) {
		if (WriterThread != null){
			WriterThread.setMessage(username, password, flag);
			
		}else
			Log.i("Cs", "Login");
		
	}
	
	//RoomID(6)UserID(8 String)
	public boolean addRoom(String roomID){
		if (WriterThread != null){
			message ms = new message();
			ms.setFlag(3);
			ms.setString(roomID+model.getUserid());
			ms.setSender(model.getUserid());
			WriterThread.setMessage(ms);
			
		}else
			Log.i("Cs", "Login");
		
		message ms = ReaderThread.readMessage;
		if(ms.getString().length()==16)
			return true;
		else
			return false;
	}
	
	public void askForRoomList(){
		WriterThread.setMessage("AFRL");

	}
	
	public void setClientUserID(String userID){
		WriterThread.setUserID(userID);
	}
	
	public void sendReady(){
		WriterThread.setMessage("ready");
	}
	
	public boolean playCard(message m1){
		if (WriterThread != null){
		
			WriterThread.setMessage(m1);
			return true;
		}
		else{
			return false;
		}
		
	}
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {

		temp = new Connection();
		temp.start();
		System.err.println("Start the service");
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		Log.e("Chat", "destryo onDestroy~~~");
		try {
			temp.interrupt();
			// socketThreadReaderThread.interrupt();
			// socketThreadWriterThread.interrupt();
		} catch (Exception e) {
			;
		}
		super.onDestroy();

	}
/**
 * 	                Used to call the playbaord function
 *					case 1:setTheCentralCard((String)msg.obj);break;
	                case 2:setPlayerUno();break;
	                case 3:setPlayerName((String)msg.obj);break;
	                case 4:setUser1Name((String)msg.obj);break;
	                case 5:setUser2Name((String)msg.obj);break;
	                case 6:setUser1CardNum(msg.arg1);break;
	                case 7:setUser2CardNum(msg.arg1);break;
	                case 8:
	                case 9:
	                case 10:setPlaying(msg.arg1==1);break;
	                case 11:setWin();break;
	                case 12:setLose();break;
	                case 13: update();break;
 * 
 */

	public void playBoardsetCentralCard(String card){
		Message msg= new Message();
		msg.what = 1; 
		msg.obj=card;
	  PlayBoard.handler.sendMessage(msg); 
	}
	
	public void playBoardsetUPlayerUno(){
		Message msg= new Message();
		msg.what = 2; 
	  PlayBoard.handler.sendMessage(msg); 
	}
	
	public void playBoardsetUPlayerName(String name){
		Message msg= new Message();
		msg.what = 3; 
		msg.obj=name;
	  PlayBoard.handler.sendMessage(msg); 
	}
	
	public void playBoardsetUser1Name(String name){
		Message msg= new Message();
		msg.what = 4; 
		msg.obj=name;
		PlayBoard.handler.sendMessage(msg); 
	}
	
	public void playBoardsetUser2Name(String name){
		Message msg= new Message();
		msg.what = 5; 
		msg.obj=name;
	  PlayBoard.handler.sendMessage(msg); 
	}
	
	public void playBoardsetUser1CardNum(int num){
		Message msg= new Message();
		msg.what = 6; 
		msg.arg1=num;
	  PlayBoard.handler.sendMessage(msg); 
	}
	
	public void playBoardsetUser2CardNum(int num){
		Message msg= new Message();
		msg.what = 7; 
		msg.arg1=num;
	  PlayBoard.handler.sendMessage(msg); 
	}
	
	public void playBoardsetPlaying(boolean p){
		Message msg= new Message();
		msg.what = 10; 
		if(p)
			msg.arg1=1;
		else
			msg.arg1=2;
	  PlayBoard.handler.sendMessage(msg); 
	}
	
	public void playBoardsetLose(){
		Message msg= new Message();
		msg.what = 12; 
	  PlayBoard.handler.sendMessage(msg); 
	}
	
	public void playBoardsetWin(){
		Message msg= new Message();
		msg.what = 11; 
	  PlayBoard.handler.sendMessage(msg); 
	}
	
	public void playBoardUpdate(){
			Message msg= new Message();
			msg.what = 13; 
		  PlayBoard.handler.sendMessage(msg); 
	}
	
	class Connection extends Thread {
		public Connection() {
		}

		public void run() {

			serverport = model.getServerport();

			server_ip = model.getServer_ip();
			Log.e("Chat", server_ip);
			InetAddress serverAddr;
			try {

				serverAddr = InetAddress.getByName(server_ip);
				socket = new Socket(serverAddr, serverport);
				if (socket != null)
					if (socket.isConnected()) {

						try {
							out = new ObjectOutputStream(
									socket.getOutputStream());
							in = new ObjectInputStream(socket.getInputStream());
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}

						WriterThread = new SocketWriter(out);
						ReaderThread = new SocketReader(in);
						ReaderThread.start();
						WriterThread.start();
						
					}
			} catch (Exception e) {
				Log.i("ClientService", "uuugh");

			}

		}

	}

	public void playroomStartGame() {
		// TODO Auto-generated method stub
		Message msg= new Message();
		msg.what = 1; 
		started = true;
	  	PlayRoomView.handler.sendMessage(msg); 
	}

	public void playroomListVIewCreateRoom(String obj) {
		// TODO Auto-generated method stub
		Message msg= new Message();
		msg.what = 1; 
		msg.obj=obj;
	  	PlayRoomListView.handler.sendMessage(msg); 
	}
	
	public void createRoom() {
		// TODO Auto-generated method stub
		if (WriterThread != null){
			WriterThread.setMessage(model.getUserid());
			
		}else
			Log.i("Cs", "Login");
	}

}
